#pragma once

#include <memory>
#include <QString>
#include "ISimpleChannel.h"

class QByteArray;

template <typename T> class SimpleChannel
{
public:
	SimpleChannel();

	typedef typename T::Settings Settings;
	void initialize(const Settings& settings);
	
	bool open();
	void close();

    unsigned dataAvailable();
	QString  lastError();

	unsigned receive(char* data, unsigned size);
	unsigned send(const char* data, unsigned size);

    QByteArray receive(unsigned size);
    unsigned send(const QByteArray& data);

private:
	std::tr1::shared_ptr<T> _pImpl;
    bool                    _init;
};

template <typename T>
SimpleChannel<T>::SimpleChannel() : _pImpl(new T), _init(false)
{}

template <typename T>
void SimpleChannel<T>::initialize(const Settings& settings)
{
    if (!_init)
    {
        _init = true;	 
        _pImpl->initialize(settings);
    }
}

template <typename T>
bool SimpleChannel<T>::open()
{
	return _pImpl->open();
}

template <typename T>
void SimpleChannel<T>::close()
{
	_pImpl->close();
}

template <typename T>
unsigned SimpleChannel<T>::dataAvailable()
{
	return _pImpl->dataAvailable();
}

template <typename T>
QString SimpleChannel<T>::lastError()
{
	return _pImpl->lastError();
}

template <typename T>
unsigned SimpleChannel<T>::receive(char* data, unsigned int size)
{
	return _pImpl->receiveData(data, size);
}

template <typename T>
unsigned SimpleChannel<T>::send(const char* data, unsigned int size)
{
	return _pImpl->sendData(data, size);
}

template <typename T>
QByteArray SimpleChannel<T>::receive(unsigned int size)
{
	return _pImpl->receiveData(size);
}

template <typename T>
unsigned SimpleChannel<T>::send(const QByteArray& data)
{
	return _pImpl->sendData(data);
}